#pragma once
#include <iostream>
#include <string>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

class UdpClient
{
public:
  UdpClient(int server_port, std::string server_ip)
    :_server_port(server_port)
     ,_server_ip(server_ip)
     ,_sockfd(-1)
  {}
  bool UdpClientInit()
  {
    // 创建套接字
    _sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (_sockfd < 0){
      std::cerr << "sockfd creat fail" << std::endl;
      return false;
    }
    std::cout << "sockfd creat success, sockfd: " << _sockfd << std::endl;
    // 不需要绑定端口号，sendto会自动分配一个，且该端口号会变
    return true;
  }
  void UdpClientStart()
  {
    struct sockaddr_in peer;
    memset(&peer, '\0', sizeof(peer));

    peer.sin_family = AF_INET;
    peer.sin_port = htons(_server_port);
    peer.sin_addr.s_addr = inet_addr(_server_ip.c_str());
    
    std::string msg;
    
    while (1){
      std::cout << "Please Enter# ";
      getline(std::cin,  msg);
      /**ssize_t send_size = **/sendto(_sockfd, msg.c_str(), msg.size(), 0, (struct sockaddr*)&peer, sizeof(peer));
      //std::cout << "send_size : " << send_size << std::endl;
      if (strcmp(msg.c_str(), "exit") == 0)
        break;
      char buf[1024];
      struct sockaddr temp;
      socklen_t len = sizeof(temp);
      ssize_t size = recvfrom(_sockfd, buf, sizeof(buf)-1, 0, (struct sockaddr*)&temp, &len);
      if (size > 0){
        buf[size] = 0;
        std::cout << buf << std::endl;
      }
    }
  }

  ~UdpClient()
  {
    if (_sockfd >= 0){
      close(_sockfd);
    }
  }
private:
  int _server_port;
  std::string _server_ip;
  int _sockfd; 
};
